package model

import (
	"encoding/json"
	"fmt"
	"retalk/common/entity"

	"github.com/garyburd/redigo/redis"
)

//服务器启动时就初始化一个UserDao实例
//讲UserDao实例做成全局变量
var (
	MyUserDao *UserDao
)

type UserDao struct {
	pool *redis.Pool
}

//使用工厂模式创建UserDao实例
func NewUserDao(pool *redis.Pool) (userDao *UserDao) {
	userDao = &UserDao{
		pool: pool,
	}
	return
}

//通过Id获取用户
func (this *UserDao) getUserById(conn redis.Conn, id int) (user *entity.User, err error) {
	//通过id去redis查询用户
	res, err := redis.String(conn.Do("HGET", "users", id))
	if err != nil {
		if err == redis.ErrNil { //没有找到对应的id
			err = ERROR_USER_NOTEXISTS
			fmt.Println("没有找到对应的id...")
		}
		return
	}

	//将res反序列化成User实例
	user = &entity.User{}
	err = json.Unmarshal([]byte(res), user)
	if err != nil {
		fmt.Println("json.Unmarshal 出错，err=", err)
		return
	}
	fmt.Println("从数据库中取出User：", user)
	return user, nil
}

//完成登录的校验 Login
//如果 用户名和密码 正确，返回User
//如果 用户名和密码 不正确，返回对应的错误信息
func (this *UserDao) Login(userid int, userpwd string) (user *entity.User, err error) {
	//从 UserDao 连接池中取出连接
	conn := this.pool.Get()
	defer conn.Close()
	user, err = this.getUserById(conn, userid)
	if err != nil {
		return
	}

	//验证密码
	if userpwd != user.UserPwd { //密码不正确
		err = ERROR_USER_PWD
		return
	}
	return
}

//注册用户:将用户信息放到数据库
func (this *UserDao) Register(user *entity.User) (err error) {
	//从 UserDao 连接池中取出连接
	conn := this.pool.Get()
	defer conn.Close()
	_, err = this.getUserById(conn, user.UserId)
	if err == nil { //用户已存在
		err = ERROR_USER_EXISTS
		return
	}

	//将用户信息放入数据库
	data, err := json.Marshal(user)
	if err != nil {
		fmt.Println("Register json.Marshal发生错误,err=", err)
		return
	}

	//入库
	_, err = conn.Do("HSET", "users", user.UserId, string(data))
	if err != nil {
		fmt.Println("Register 保存用户信息到数据库时发生错误,err=", err)
		return
	}
	return
}
